//
//  SHMultithreadViewController.m
//  SDemo
//
//  Created by gg on 2018/7/16.
//  Copyright © 2018年 gg. All rights reserved.
//

#import "SHMultithreadViewController.h"

@interface SHMultithreadViewController ()

@end

@implementation SHMultithreadViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"多线程详解";
    self.view.backgroundColor = [UIColor cyanColor];
    
    [self initData];
}

-(void)initData {
    /**
     多线程（multithreading），是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程，进而提升整体处理性能。
     
     原理：
     同一时间，CPU只能处理1条线程，只有1条线程在工作（执行）
     多线程并发（同时）执行，其实是CPU快速地在多条线程之间调度（切换）
     如果CPU调度线程的时间足够快，就造成了多线程并发执行的假象
     注意：多线程并发，并不是cpu在同一时刻同时执行多个任务，只是CPU调度足够快，造成的假象。
     
     优点：
     能适当提高程序的执行效率
     能适当提高资源利用率（CPU、内存利用率）
     
     缺点：
     开启线程需要占用一定的内存空间（默认情况下，主线程占用1M，子线程占用512KB），如果开启大量的线程，会占用大量的内存空间，降低程序的性能
     线程越多，CPU在调度线程上的开销就越大
     
     
     主要是四种 pthread(c) NSThread(oc) GCD(c) NSOperation(oc)
    
     */
    
    //NSThread 常用方法
    NSLog(@"当前线程 -- %@", [NSThread currentThread]); //1 表示主线程
//    [NSThread sleepForTimeInterval:1];
//    NSLog(@"睡眠结束");
    
    //创建线程的三种方法
    //1
   // [NSThread detachNewThreadSelector:@selector(newThread) toTarget:self withObject:nil];
    
    //2
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething) object:nil];
    //调度
    [thread start];
    NSLog(@"线程前的stackSize ： %lu",(unsigned long)thread.stackSize);
    if (!thread.isCancelled) {
        [thread cancel];
    } else {
        NSLog(@"线程前的stackSize ： %lu",(unsigned long)thread.stackSize);
    }
    
    
//    NSLog(@"thread -- %@",thread);
    
    //3
    //[self performSelectorInBackground:@selector(doNewSomething) withObject:nil];
    
    
    /**
     线程的状态
     */
    
    
    /**
     线程的安全问题
     多个线程访问同一块资源进行读写，如果不加控制随意访问容易产生数据错乱从而引发数据安全问题。
     为了解决这一问题，就有了加锁的概念。加锁的原理就是当有一个线程正在访问资源进行写的时候，不
     允许其他线程再访问该资源，只有当该线程访问结束后，其他线程才能按顺序进行访问。对于读取数
     据，有些程序设计是允许多线程同时读的，有些不允许。UIKit中几乎所有控件都不是线程安全的，因
     此需要在主线程上更新UI。
     
     下面是几种解决方案:
     */
    
    /**
    1, 互斥锁
     注意：锁定1份代码只用1把锁，用多把锁是无效的
     @synchronized(锁对象) { // 需要锁定的代码  }
     尽量少用
     
     2,使用NSLock对象
     3,atomic加锁
     
     iOS开发的建议:
     （1）所有属性都声明为nonatomic
     （2）尽量避免多线程抢夺同一块资源
     （3）尽量将加锁、资源抢夺的业务逻辑交给服务器端处理，减小移动客户端的压力
     
     */
    
    
    
}

-(void) newThread {
    NSLog(@"这是一条新线程");
}

-(void)doSomething {
    NSLog(@"新线程");
}

-(void)doNewSomething {
    NSLog(@"其他线程");
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
   
}



@end
